package Controller;

import Model.AIPlayer;
import Model.Board;
import Model.HumanPlayer;
import View.BeginView;
import View.GameView;

import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.util.Random;

/**
 * 游戏主控制器，协调Model和View的交互
 * 处理游戏流程和规则控制
 */
public class GameController {

    private final ButtonController bc;
    private final MenuController mc;
    private final BeginView bv;
    private final GameView gv;
    private final Board board;

    public GameController(){

        bv = new BeginView();
        bc = new ButtonController();
        mc = new MenuController();
        gv = new GameView(mc,bc);
        board = new Board();
        bc.setBoard(board);
        bc.setGameController(this);

    }

    /**
     * 游戏初始化方法
     * 显示开始界面并根据用户选择启动对应游戏模式
     * @throws InterruptedException 线程休眠可能抛出异常
     */
    public void init() throws InterruptedException {

        bv.display();

        if (bv.getModeloption() != -1){
            gv.display();
            bc.setGamemodel(bv.getModeloption());

            if (bv.getModeloption() == 1){
                HumanPlayer human = new HumanPlayer("X");
                AIPlayer ai = new AIPlayer("O");
                bc.setHumanPlayer(human);
                bc.setAIPlayer(ai);
                ai.setBoard(board);
            }

            if (bv.getModeloption() == 2){
                AIPlayer ai1 = new AIPlayer("X");
                AIPlayer ai2 = new AIPlayer("O");
                ai1.setBoard(board);
                ai2.setBoard(board);
                startmodel3(ai1,ai2);
            }

        }

    }

    /**
     * 处理游戏结束逻辑
     * 显示游戏结果并提供重新开始选项
     * 根据玩家选择重新开始游戏或退出
     */
    public void gamerover(){
        int result = board.Judge();

        String message;
        if (result == board.getWin()) message = "X方获胜";
        else if (result == board.getLose()) message = "O方获胜";
        else message = "平局";

        JLabel resultMessage = new JLabel(message);
        resultMessage.setFont(new Font(null,Font.BOLD,16));
        JOptionPane.showMessageDialog(null,resultMessage,"提示",JOptionPane.PLAIN_MESSAGE);


        JLabel againMessage = new JLabel("再来一局?");
        againMessage.setFont(new Font(null,Font.BOLD,16));
        int over = JOptionPane.showConfirmDialog(null,againMessage,"提示",
                JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE);

        //出去上面弹窗按钮，实现重新开始或退出游戏
        if (over == JOptionPane.YES_OPTION){
            //重新开始游戏逻辑，和MenuController中的逻辑相同
            try {
                // 获取当前工作目录
                String currentDir = System.getProperty("user.dir");

                ProcessBuilder builder = new ProcessBuilder(
                        System.getProperty("java.home") + "/bin/java",
                        "-cp", System.getProperty("java.class.path"),
                        "main"
                );

                // 使用当前工作目录作为相对路径
                builder.directory(new java.io.File(currentDir));
                builder.start();
                System.exit(0);
            } catch (IOException e) {
                e.printStackTrace();
                System.exit(1);
            }

        }else {
            System.exit(0);
        }
    }

    /**
     * 机机对战模式实现
     * 两个AI自动对战，使用minimax算法决策
     * 控制游戏节奏，每步间隔1秒
     */
    private void startmodel3(AIPlayer ai1,AIPlayer ai2)  {

        //第一个落子由ai1随机下
        Random r = new Random();
        int index = r.nextInt(9);

        gv.getJb()[index].setText(ai1.getName());
        gv.getJb()[index].setEnabled(false);
        board.setState(index,gv.getJb()[index].getText());
        //后面使用ai逻辑一直下，直到游戏结束
        while (true) {
            if (board.Judge() == 1){run(ai2);}else {break;}
            if (board.Judge() == 1){run(ai1);}else {break;}
        }
        //进行游戏结束操作
        int result = board.Judge();
        if (result == board.getWin() || result == board.getLose() || result == board.getDraw()) {
            gamerover();
        }
    }
    //两个ai下棋的逻辑
    private void run(AIPlayer ai){
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        int next = ai.minimax(board.getState());
        gv.getJb()[next].setText(ai.getName());
        gv.getJb()[next].setEnabled(false);
        board.setState(next,gv.getJb()[next].getText());
    }

}
